package com.hfzy.ihk.web.aliyuncall.biz;

import com.alibaba.fastjson.JSONObject;
import com.hfzy.ihk.common.support.againtask.DelayQueueManager;
import com.hfzy.ihk.common.support.againtask.DelayWorker;
import com.hfzy.ihk.common.util.date.DateUtils;
import com.hfzy.ihk.common.util.http.HttpClientUtils;
import com.hfzy.ihk.common.util.http.HttpRequester;
import com.hfzy.ihk.common.util.string.StringTools;
import com.hfzy.ihk.facade.aliyuncall.enums.MsgTypeEnum;
import com.hfzy.ihk.web.aliyuncall.constant.RedisFields;
import com.hfzy.ihk.web.aliyuncall.constant.RedisKey;
import com.hfzy.ihk.web.aliyuncall.vo.VoiceRTASRReportVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.HashMap;

import java.util.Map;

/**
 * Created by YANFA on 2018/8/28.
 */
@Component
public class PushDataToAnalysis {

    @Value("${pushdata.ai.url}")
    private String url;


    @Value("${pushdata.ai.asr-url}")
    private String asrUrl;

    @Autowired
    private RedisTemplate redisTemplate;


    private static final Logger logger = LoggerFactory.getLogger(PushDataToAnalysis.class);

    /**
     * 通过http post 数据到分析服务，如果推送失败进行重试，一定次数以后抛弃
     * @param sessionId
     * @param data
     * @param msgType ----消息类型 end：结束消息，normal：普通消息，mute：静音
     */
    @Async("pushDataToAnalysisTaskExecutor")
    public void pushData(String packageId,String callTaskId,String sessionId,VoiceRTASRReportVo data,String callType,String msgType){
        Map<String,Object> rmap = new HashMap<>();
        Map<String,Object> map = new HashMap<>();

        try{
            map.put("session_id",sessionId);
            map.put("call_task_id",callTaskId);
            map.put("package_id",packageId);
            map.put("date_time", DateUtils.formatDate(new Date()));
            map.put("word_id",data.getWordId());
            map.put("call_type",callType);//是双呼还是ASR智能外呼
            map.put("msg_type",msgType);

            if(MsgTypeEnum.NORMAL.getValue().equals(msgType)) {  //普通消息
                if (StringTools.isEmpty(data.getWords()) || StringTools.isEmpty(data.getOut_id()))
                    return;
                map.put("data", data.getWords());
                if (StringTools.isEmpty(data.getBegin_offset()))
                    map.put("begin_offset", 0L);
                else
                    map.put("begin_offset", data.getBegin_offset());

                if (StringTools.isEmpty(data.getEnd_offset()))
                    map.put("end_offset", 0L);
                else
                    map.put("end_offset", data.getEnd_offset());

                if (StringTools.isNotempty(data.getRole()) && "A".equals(data.getRole())) {
                    map.put("type", "customer");
                } else if (StringTools.isNotempty(data.getRole()) && "B".equals(data.getRole())) {
                    map.put("type", "broker");
                }
            }
            rmap.put("data",map);
            //post发送
            try{
                logger.info(">>>>>>>>>>>>双呼推送到分析服务器数据：{}",JSONObject.toJSONString(rmap));
                HttpClientUtils.postWithJson(url,JSONObject.toJSONString(rmap));
            }catch (Exception e){
                logger.error("推送失败放入重试队列，sessionId:{},data:{}",sessionId, JSONObject.toJSONString(data),e);
                DelayWorker delayWorker = new DelayWorker(3,500,()->{
                    HttpRequester httpRequester = new HttpRequester();
                    httpRequester.sendJSONObjectPost(url,new JSONObject(rmap),null);
                });
                DelayQueueManager.getInstance().put(delayWorker);
            }

        }catch (Exception e){
            logger.error("解析语音识别数据错误data:{}",data,e);
        }

    }


    /**
     * asr 外呼识别结果回来推送到分析服务器，这里必须采用同步操作
     * @param packageId
     * @param callTaskId
     * @param sessionId
     *
     * @param data
     * @param callType
     * @param msgType ----消息类型 end：结束消息，normal：普通消息，mute：静音
     * @return
     */
    public String pushAsrData(String packageId,String callTaskId,String sessionId,VoiceRTASRReportVo data,String callType,String msgType){
        Map<String,Object> rmap = new HashMap<>();
        Map<String,Object> map = new HashMap<>();
        try{
            map.put("session_id",sessionId);
            map.put("call_task_id",callTaskId);
            map.put("package_id",packageId);
            map.put("date_time", DateUtils.formatDate(new Date()));
            map.put("word_id",data.getWordId());
            map.put("call_type",callType);//是双呼还是ASR智能外呼
            map.put("msg_type",msgType);
            if(MsgTypeEnum.NORMAL.getValue().equals(msgType)){ //普通消息
                if(StringTools.isEmpty(data.getWords())||StringTools.isEmpty(data.getOut_id()))
                    return null;
                map.put("data", data.getWords());
                if(StringTools.isEmpty(data.getBegin_offset()))
                    map.put("begin_offset",0L);
                else
                    map.put("begin_offset",data.getBegin_offset());

                if(StringTools.isEmpty(data.getEnd_offset()))
                    map.put("end_offset",0L);
                else
                    map.put("end_offset",data.getEnd_offset());

                if(StringTools.isNotempty(data.getRole())&&"A".equals(data.getRole())){
                    map.put("type", "customer");
                }else if(StringTools.isNotempty(data.getRole())&&"B".equals(data.getRole())){
                    map.put("type", "broker");
                }
            }
            rmap.put("data",map);
            //post发送
            logger.info(">>>>>>>>>>>>>发送给分析服务器的消息：{}",JSONObject.toJSONString(rmap));
            String rs= HttpClientUtils.postWithJson(asrUrl,JSONObject.toJSONString(rmap));
            logger.info(">>>>>>>>>>rs:{}",rs);
            return rs;
        }catch (Exception e){
            logger.error("解析语音识别数据错误data:{}",data,e);
            return null;
        }

    }


    public String[] readPackageIdAndCallTaskId(String sessionId){
        //读取redis
        try {
            Object callTaskId = redisTemplate.opsForValue().get(sessionId);
            if (callTaskId != null) {
                String[] packageIdAndCallTaskIds = String.valueOf(callTaskId).split(":");
                return packageIdAndCallTaskIds;

            } else {
                return null;
            }
        }catch (Exception e){
            logger.error("获取redis taskId 异常sessionId：{}",sessionId,e);
            return null;
        }
    }
}
